﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace HeliGame
{


    class Target
    {
        Model model;
        Matrix[] modelTransforms;
        public Texture texture;
        Vector3 position;
        BoundingBox boundingBox;
        float bottom, up;


        public BoundingSphere GetBounidingSphere()
        {

            ModelMesh mesh = model.Meshes.First();
            Matrix worldMatrix = Matrix.CreateTranslation(position);
            BoundingSphere bs = mesh.BoundingSphere;
            bs = bs.Transform(worldMatrix);
            return bs;
         
        }


        public RotatedBBox RotatedBoundingBox
        {
            get
            {
                Vector3 min = boundingBox.Min, max = boundingBox.Max;
                RotatedBBox rbbox;
                rbbox.v1 = min;
                rbbox.v2 = new Vector3(max.X, min.Y, min.Z);
                rbbox.v3 = new Vector3(max.X, min.Y, max.Z);
                rbbox.v4 = new Vector3(min.X, min.Y, max.Z);
                rbbox.height = max.Y - min.Y;

                Matrix transformation = Matrix.CreateTranslation(position);

                rbbox.v1 = Vector3.Transform(rbbox.v1, transformation);
                rbbox.v2 = Vector3.Transform(rbbox.v2, transformation);
                rbbox.v3 = Vector3.Transform(rbbox.v3, transformation);
                rbbox.v4 = Vector3.Transform(rbbox.v4, transformation);

                return rbbox;
            }
        }

        private BoundingBox CalcBoundingBox()
        {
            Vector3 modelMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
            Vector3 modelMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);

            foreach (ModelMesh mesh in model.Meshes)
            {
                Vector3 meshMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
                Vector3 meshMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);

                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    int stride = part.VertexBuffer.VertexDeclaration.VertexStride;

                    Vector3[] vertexData = new Vector3[part.NumVertices];

                    part.VertexBuffer.GetData<Vector3>(part.VertexOffset * stride, vertexData,
                        0, vertexData.Length, stride);

                    for (int i = 0; i < vertexData.Length; i++)
                    {
                        meshMin = Vector3.Min(meshMin, vertexData[i]);
                        meshMax = Vector3.Max(meshMax, vertexData[i]);
                    }
                }

                meshMin = Vector3.Transform(meshMin, modelTransforms[mesh.ParentBone.Index]);
                meshMax = Vector3.Transform(meshMax, modelTransforms[mesh.ParentBone.Index]);

                modelMin = Vector3.Min(modelMin, meshMin);
                modelMax = Vector3.Max(modelMax, meshMax);
            }

            bottom = modelMin.Y;
            up = modelMax.Z;
            return new BoundingBox(modelMin, modelMax);
        }

        
        public void setRandomPosition(Random r)
        {
            float positionX = (float)r.NextDouble() * 8.0f + 1.0f;
            float positionY = (float)r.NextDouble() * 3.0f + 1.0f;
            float positionZ = (float)r.NextDouble() * 10.0f + 1.0f;
            positionZ = -positionZ;
            position = new Vector3(positionX, positionY, positionZ);

        }

        public void setRandomPosition1(Random r)
        {
            position = new Vector3(6.44f, 3.81f, -4.27f);
        }

 

        public Target(Model model, Texture texture = null)
        {
            this.model = model;
            this.texture = texture;
            modelTransforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(modelTransforms);
            boundingBox = CalcBoundingBox();
        }

        public void SetEffect(Effect effect)
        {
            foreach (ModelMesh mesh in model.Meshes)
                foreach (ModelMeshPart meshPart in mesh.MeshParts)
                    meshPart.Effect = effect;
        }


        public void Draw(GraphicsDevice device)
        {
            
            Matrix worldMatrix = Matrix.CreateTranslation(position);
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (Effect currentEffect in mesh.Effects)
                {
                    currentEffect.Parameters["xWorld"].SetValue(worldMatrix);
                    //currentEffect.Parameters["xLightPosition"].SetValue(new Vector3(0, 4.5f, 2));
                }
                mesh.Draw();
            }
             

        }

     
        
    }
}
